package cn.tedu.charging.order.websocket;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Component
@ServerEndpoint("/ws/server/{userId}")// 这个注解相当于一个标识,标识这个类是一个websocket服务
public class WebSocketServer {

    //使用ConcurrentHashMap是为了在多线程环境下安全地存储和访问Session对象。
    //ConcurrentHashMap是线程安全的哈希表，支持高并发操作，避免了多线程竞争导致的线程安全问题，同时提供了较好的性能表现。
    private static ConcurrentHashMap<Integer, Session> sessions = new ConcurrentHashMap<>();

    /**
     * 发送消息,服务端给用户发送消息
     * @param userId 表示给谁发
     * @param message 发什么消息
     */
    public void sendMessage(Integer userId,String message){
        Session session = sessions.get(userId);
        if (session != null){
            try {
                /**
                 *
                 getBasicRemote() 返回的是 RemoteEndpoint.Basic 对象，
                 该对象提供的是同步发送消息的方法。同步发送意味着发送操作会阻塞当前线程，
                 直到消息成功发送或发生异常。如果需要异步发送消息，
                 应使用 getAsyncRemote() 方法返回的 RemoteEndpoint.Async 对象。
                 */
                session.getBasicRemote().sendText(message);
            }catch (IOException e){
                throw new RuntimeException(e);
            }
        }else {
            log.error("用户:{},已经下线",userId);
        }
    }

    /**
     * 连接建立成功调用的方法
     * @param session 会话状态
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("userId") Integer userId) {
        log.debug("onOpen");
        sessions.put(userId,session);
        log.debug("用户:{},连接成功:{}",userId,session);
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(Session session, @PathParam("userId") Integer userId) {
        log.debug("onClose");
        sessions.remove(userId);
        log.debug("用户:{},退出:{}",userId,session);
    }

    /**
     * 消息到达，用户到服务端（订单服务）
     * @param message
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        log.debug("onMessage");
        log.debug("用户:{},发送消息:{},",session,message);
    }

    /**
     * 出现问题时调用此方法，具体的错误原因 throwable，谁出现的问题呢 session
     */
    @OnError
    public void onError(Session session, Throwable throwable) {
        log.error("onError");
        log.error("发生错误:{},会话状态:{}",throwable,session);
    }




}
